import { store } from '@/store'
import type { UserInfo } from '@/types'

// 路由配置类型
export interface RouteConfig {
  path: string
  name?: string
  meta?: {
    title?: string
    requiresAuth?: boolean
    roles?: string[]
    permissions?: string[]
    keepAlive?: boolean
    showTabBar?: boolean
  }
}

// 路由守卫类型
export interface RouteGuard {
  beforeEnter?: (
    to: RouteConfig,
    from?: RouteConfig
  ) => boolean | Promise<boolean>
  afterEnter?: (to: RouteConfig, from?: RouteConfig) => void
}

// 路由管理类
class RouterManager {
  private routes: Map<string, RouteConfig> = new Map()
  private guards: RouteGuard[] = []

  constructor() {
    this.initRoutes()
  }

  // 初始化路由配置
  private initRoutes(): void {
    const routeConfigs: RouteConfig[] = [
      {
        path: '/src/pages/index/index',
        name: 'Home',
        meta: {
          title: '首页',
          requiresAuth: false,
          showTabBar: true,
        },
      },
      {
        path: '/src/pages/login/login',
        name: 'Login',
        meta: {
          title: '用户登录',
          requiresAuth: false,
          showTabBar: false,
        },
      },
      {
        path: '/src/pages/register/register',
        name: 'Register',
        meta: {
          title: '用户注册',
          requiresAuth: false,
          showTabBar: false,
        },
      },
    ]

    routeConfigs.forEach((route) => {
      this.routes.set(route.path, route)
    })
  }

  // 添加路由
  addRoute(route: RouteConfig): void {
    this.routes.set(route.path, route)
  }

  // 获取路由配置
  getRoute(path: string): RouteConfig | undefined {
    return this.routes.get(path)
  }

  // 添加路由守卫
  addGuard(guard: RouteGuard): void {
    this.guards.push(guard)
  }

  // 执行路由守卫
  private async executeGuards(
    to: RouteConfig,
    from?: RouteConfig,
    type: 'beforeEnter' | 'afterEnter' = 'beforeEnter'
  ): Promise<boolean> {
    for (const guard of this.guards) {
      const handler = guard[type]
      if (handler) {
        if (type === 'beforeEnter') {
          const result = await handler(to, from)
          if (result === false) {
            return false
          }
        } else {
          handler(to, from)
        }
      }
    }
    return true
  }

  // 导航到指定页面
  async navigateTo(
    path: string,
    options?: UniApp.NavigateToOptions
  ): Promise<boolean> {
    const route = this.getRoute(path)
    if (!route) {
      console.warn(`Route not found: ${path}`)
      return false
    }

    // 执行前置守卫
    const canEnter = await this.executeGuards(route, undefined, 'beforeEnter')
    if (!canEnter) {
      return false
    }

    // 执行导航
    try {
      await new Promise<void>((resolve, reject) => {
        uni.navigateTo({
          url: path,
          ...options,
          success: () => {
            this.executeGuards(route, undefined, 'afterEnter')
            resolve()
          },
          fail: reject,
        })
      })
      return true
    } catch (error) {
      console.error('Navigation failed:', error)
      return false
    }
  }

  // 重定向到指定页面
  async redirectTo(path: string, options?: any): Promise<boolean> {
    const route = this.getRoute(path)
    if (!route) {
      console.warn(`Route not found: ${path}`)
      return false
    }

    // 执行前置守卫
    const canEnter = await this.executeGuards(route, undefined, 'beforeEnter')
    if (!canEnter) {
      return false
    }

    // 执行重定向
    try {
      await new Promise<void>((resolve, reject) => {
        uni.redirectTo({
          url: path,
          ...options,
          success: () => {
            this.executeGuards(route, undefined, 'afterEnter')
            resolve()
          },
          fail: reject,
        })
      })
      return true
    } catch (error) {
      console.error('Redirect failed:', error)
      return false
    }
  }

  // 重新启动到指定页面
  async reLaunch(
    path: string,
    options?: UniApp.ReLaunchOptions
  ): Promise<boolean> {
    const route = this.getRoute(path)
    if (!route) {
      console.warn(`Route not found: ${path}`)
      return false
    }

    // 执行前置守卫
    const canEnter = await this.executeGuards(route, undefined, 'beforeEnter')
    if (!canEnter) {
      return false
    }

    // 执行重启
    try {
      await new Promise<void>((resolve, reject) => {
        uni.reLaunch({
          url: path,
          ...options,
          success: () => {
            this.executeGuards(route, undefined, 'afterEnter')
            resolve()
          },
          fail: reject,
        })
      })
      return true
    } catch (error) {
      console.error('ReLaunch failed:', error)
      return false
    }
  }

  // 切换标签页
  async switchTab(
    path: string,
    options?: UniApp.SwitchTabOptions
  ): Promise<boolean> {
    const route = this.getRoute(path)
    if (!route) {
      console.warn(`Route not found: ${path}`)
      return false
    }

    // 执行前置守卫
    const canEnter = await this.executeGuards(route, undefined, 'beforeEnter')
    if (!canEnter) {
      return false
    }

    // 执行切换
    try {
      await new Promise<void>((resolve, reject) => {
        uni.switchTab({
          url: path,
          ...options,
          success: () => {
            this.executeGuards(route, undefined, 'afterEnter')
            resolve()
          },
          fail: reject,
        })
      })
      return true
    } catch (error) {
      console.error('SwitchTab failed:', error)
      return false
    }
  }

  // 返回上一页
  back(delta: number = 1): void {
    uni.navigateBack({ delta })
  }

  // 获取当前页面路径
  getCurrentPath(): string {
    // #ifdef H5
    if (typeof (globalThis as any).getCurrentPages === 'function') {
      const pages = (globalThis as any).getCurrentPages()
      if (pages.length > 0) {
        return `/${pages[pages.length - 1].route}`
      }
    }
    // #endif
    return ''
  }

  // 检查是否有权限访问页面
  hasPermission(route: RouteConfig, userInfo?: UserInfo | null): boolean {
    if (!route.meta?.requiresAuth) {
      return true
    }

    if (!userInfo) {
      return false
    }

    // 检查角色权限
    if (route.meta.roles && route.meta.roles.length > 0) {
      const userRoles = userInfo.roles || []
      const hasRole = route.meta.roles.some((role) => userRoles.includes(role))
      if (!hasRole) {
        return false
      }
    }

    // 检查具体权限
    if (route.meta.permissions && route.meta.permissions.length > 0) {
      const userPermissions = userInfo.permissions || []
      const hasPermission = route.meta.permissions.some((permission) =>
        userPermissions.includes(permission)
      )
      if (!hasPermission) {
        return false
      }
    }

    return true
  }
}

// 创建路由管理器实例
export const router = new RouterManager()

// 添加默认路由守卫
router.addGuard({
  beforeEnter: (to, from) => {
    // 检查是否需要登录
    if (to.meta?.requiresAuth && !store.isLoggedIn) {
      uni.showToast({
        title: '请先登录',
        icon: 'none',
        duration: 2000,
      })

      // 跳转到登录页
      setTimeout(() => {
        router.reLaunch('/src/pages/login/login')
      }, 1000)

      return false
    }

    // 检查权限
    if (!router.hasPermission(to, store.userInfo)) {
      uni.showToast({
        title: '没有访问权限',
        icon: 'none',
        duration: 2000,
      })
      return false
    }

    // 设置页面标题
    if (to.meta?.title) {
      uni.setNavigationBarTitle({
        title: to.meta.title,
      })
    }

    return true
  },
})

// 导出便捷方法
export const navigateTo = router.navigateTo.bind(router)
export const redirectTo = router.redirectTo.bind(router)
export const reLaunch = router.reLaunch.bind(router)
export const switchTab = router.switchTab.bind(router)
export const back = router.back.bind(router)
export const getCurrentPath = router.getCurrentPath.bind(router)

export default router
